package edu.scut.dap.entity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;

/**
 * Created by Alex on 2016/12/6.
 */
public class TaskState {
    private String taskName;
    private Process process;
    private Integer exitCode;
    private String outputMessage;
    private String errorMessage;
    private long startTime;
    private long endTime;

    private Thread updateOutputMessage=new Thread(new Runnable() {
        @Override
        public void run() {
            BufferedReader reader=new BufferedReader(new InputStreamReader(process.getInputStream()));
            if (process != null) {
                System.out.println("process is not null");
            }
            String line;
            try {
                while ((line=reader.readLine())!=null){
                    addOutputMessage(line);
                    System.out.println(line);
                }
                setTimestampNow();
            } catch (IOException e) {
                e.printStackTrace();
                addOutputMessage("Fail to get output message, now time is "+new Date().toLocaleString());
            }
        }
    });

    private Thread updateErrorMessage=new Thread(new Runnable() {
        @Override
        public void run() {
            BufferedReader reader=new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String line;
            try {
                while ((line=reader.readLine())!=null){
                    addErrorMessage(line);
                }
                setTimestampNow();
            } catch (IOException e) {
                e.printStackTrace();
                addErrorMessage("Fail to get error message, now time is "+new Date().toLocaleString());
            }
        }
    });

    public void startUpdateMessage(){
        updateOutputMessage.start();
        updateErrorMessage.start();
    }

    public TaskState setTaskName(String taskName) {
        this.taskName = taskName;
        return this;
    }

    public TaskState setProcess(Process process) {
        this.process = process;
        return this;
    }

    private void addOutputMessage(String outputMessage) {
        if (this.outputMessage==null){
            this.outputMessage=outputMessage+"\n";
        }else{
            this.outputMessage+=outputMessage+"\n";
        }
    }

    private void addErrorMessage(String errorMessage) {
        if (this.errorMessage==null){
            this.errorMessage=errorMessage+"\n";
        }else{
            this.errorMessage+=errorMessage+"\n";
        }
    }

    public TaskState setTimestampNow() {
        if (startTime==0){
            startTime=new Date().getTime();
        }else if (endTime==0){
            endTime=new Date().getTime();
        }
        return this;
    }

    public String getTaskName() {
        return taskName;
    }

    public Integer getExitCode() {
        if (process!=null){
            try{
                exitCode=process.exitValue();
                setTimestampNow();
                while (updateOutputMessage.isAlive()||updateErrorMessage.isAlive());
                process=null;
            }catch (IllegalThreadStateException e){
                exitCode=-1;    //process is still running
            }
        }
        return exitCode;
    }

    public String getOutputMessage() {
        return outputMessage;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public Long getRunTime() {
        if (startTime!=0&&endTime!=0){
            return endTime-startTime;
        }else {
            return 0L;
        }
    }
}
